package com.qby.common.utils.sql;



import com.qby.common.exceptions.BusinessException;
import com.qby.common.utils.StringUtils;
import com.qby.common.utils.reflect.ReflectUtils;
import tk.mybatis.mapper.entity.Example;

import javax.persistence.Transient;
import java.lang.reflect.Field;
import java.util.List;

/**
 * sql操作工具类
 *
 * @author ruoyi
 */
public class SqlUtil {
    /**
     * 仅支持字母、数字、下划线、空格、逗号（支持多个字段排序）
     */
    public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,]+";

    /**
     * 检查字符，防止注入绕过
     */
    public static String escapeOrderBySql(String value) {
        if (StringUtils.isNotEmpty(value) && !isValidOrderBySql(value)) {
            return StringUtils.EMPTY;
        }
        return value;
    }

    /**
     * 验证 order by 语法是否符合规范
     */
    public static boolean isValidOrderBySql(String value) {
        return value.matches(SQL_PATTERN);
    }


    /**
     * 构建example查询
     */
    public static Example newExample(Class clazz) {
        if (clazz != null) {
            return new Example(clazz, true, true);
        }
        return null;
    }

    public static Example newExample(Object obj) {
        if (obj != null) {
            Class<?> clazz = obj.getClass();
            Example example = new Example(clazz);
            Example.Criteria criteria = example.createCriteria();

            Field[] allFields = clazz.getDeclaredFields();
            for (Field field : allFields) {
                Transient aTransient = field.getAnnotation(Transient.class);
                if (aTransient != null) {
                    continue;
                }
                String name = field.getName();
                Object val = ReflectUtils.getFieldValue(obj, name);
                if (val == null) {
                    continue;
                }

                Class<?> type = field.getType();
                if (type.equals(String.class)) {
                    if (StringUtils.isBlank((String) val)) {
                        continue;
                    }
                }
                criteria.andEqualTo(name, val);
            }
            criteria.andEqualTo("deleteStatus", 0);
            return example;
        }
        return null;
    }

    public static Example.Criteria createCriteria(Example example) {
        if (example == null) {
            throw new BusinessException("example is null");
        }
        List<Example.Criteria> oredCriteria = example.getOredCriteria();
        if (oredCriteria == null || oredCriteria.isEmpty()) {
            throw new BusinessException("example is null");
        }
        return oredCriteria.get(0);
    }

}
